/**
 * 任务检测器 (TaskDetector)
 * 
 * 识别聊天记录中的任务需求，提取任务信息
 * Requirements: 4.1
 */

import type { ParsedChat, DetectedTask, TaskPriority, ApiChatMessage } from '../types';
import { GitCodeApiService, defaultApiService } from './GitCodeApiService';

/**
 * 任务检测器接口
 */
export interface ITaskDetector {
  detect(chat: ParsedChat): Promise<DetectedTask[]>;
  hasTask(chat: ParsedChat): Promise<boolean>;
}

/**
 * LLM 返回的任务结构
 */
interface LLMTaskResponse {
  tasks: Array<{
    description: string;
    participants: string[];
    deadline?: string;
    priority: string;
  }>;
}

/**
 * 任务检测器实现
 */
export class TaskDetector implements ITaskDetector {
  private apiService: GitCodeApiService;

  constructor(apiService: GitCodeApiService = defaultApiService) {
    this.apiService = apiService;
  }

  /**
   * 检测聊天记录中的任务
   * 
   * @param chat - 解析后的聊天记录
   * @returns 检测到的任务列表，如果没有任务则返回空数组
   * Requirements: 4.1, 7.3
   */
  async detect(chat: ParsedChat): Promise<DetectedTask[]> {
    // 如果聊天记录为空，直接返回空数组
    if (!chat.messages || chat.messages.length === 0) {
      return [];
    }

    try {
      const prompt = this.buildDetectionPrompt(chat);
      const messages: ApiChatMessage[] = [
        {
          role: 'system',
          content: this.getSystemPrompt(),
        },
        {
          role: 'user',
          content: prompt,
        },
      ];

      const response = await this.apiService.chat(messages);
      return this.parseTaskResponse(response, chat.participants);
    } catch {
      // 发生错误时返回空数组而非抛出异常
      // Requirements: 7.3
      return [];
    }
  }

  /**
   * 快速检查聊天记录是否包含任务
   * 
   * @param chat - 解析后的聊天记录
   * @returns 是否包含任务
   */
  async hasTask(chat: ParsedChat): Promise<boolean> {
    const tasks = await this.detect(chat);
    return tasks.length > 0;
  }

  /**
   * 构建任务检测提示词
   */
  private buildDetectionPrompt(chat: ParsedChat): string {
    const chatContent = chat.messages
      .map(msg => `${msg.sender}: ${msg.content}`)
      .join('\n');

    return `请分析以下聊天记录，识别其中的任务需求：

聊天记录：
${chatContent}

参与者：${chat.participants.join(', ')}

请识别聊天中提到的所有任务，包括：
- 需要完成的事项
- 约定的安排
- 待办事项
- 计划或承诺

对于每个任务，请提取：
1. 任务描述
2. 相关参与者
3. 截止时间（如果有提及）
4. 优先级（high/medium/low，根据紧急程度判断）`;
  }

  /**
   * 获取系统提示词
   */
  private getSystemPrompt(): string {
    return `你是一个任务识别助手。你的任务是从聊天记录中识别任务需求。

请以 JSON 格式返回结果，格式如下：
{
  "tasks": [
    {
      "description": "任务描述",
      "participants": ["参与者1", "参与者2"],
      "deadline": "截止时间（ISO格式，如果有的话）",
      "priority": "high/medium/low"
    }
  ]
}

规则：
1. 如果没有检测到任务，返回 {"tasks": []}
2. 只返回 JSON，不要添加其他文字
3. 任务描述要简洁明了
4. 参与者只包含与该任务直接相关的人
5. 如果没有明确的截止时间，不要包含 deadline 字段
6. 根据上下文判断优先级：
   - high: 紧急、今天、马上、立刻
   - medium: 这周、近期、尽快
   - low: 有空、以后、不急`;
  }

  /**
   * 解析 LLM 返回的任务响应
   */
  private parseTaskResponse(response: string, participants: string[]): DetectedTask[] {
    try {
      // 尝试提取 JSON 内容
      const jsonMatch = response.match(/\{[\s\S]*\}/);
      if (!jsonMatch) {
        return [];
      }

      const parsed: LLMTaskResponse = JSON.parse(jsonMatch[0]);
      
      if (!parsed.tasks || !Array.isArray(parsed.tasks)) {
        return [];
      }

      return parsed.tasks.map((task, index) => this.convertToDetectedTask(task, index, participants));
    } catch {
      // 解析失败返回空数组
      return [];
    }
  }

  /**
   * 将 LLM 返回的任务转换为 DetectedTask 类型
   */
  private convertToDetectedTask(
    task: LLMTaskResponse['tasks'][0],
    index: number,
    chatParticipants: string[]
  ): DetectedTask {
    // 验证参与者是否在聊天参与者中
    const validParticipants = task.participants?.filter(p => 
      chatParticipants.some(cp => cp.toLowerCase().includes(p.toLowerCase()) || p.toLowerCase().includes(cp.toLowerCase()))
    ) || [];

    // 解析截止时间
    let deadline: Date | undefined;
    if (task.deadline) {
      const parsedDate = new Date(task.deadline);
      if (!isNaN(parsedDate.getTime())) {
        deadline = parsedDate;
      }
    }

    // 验证优先级
    const validPriorities: TaskPriority[] = ['high', 'medium', 'low'];
    const priority: TaskPriority = validPriorities.includes(task.priority as TaskPriority)
      ? (task.priority as TaskPriority)
      : 'medium';

    return {
      id: `task-${Date.now()}-${index}`,
      description: task.description || '未命名任务',
      participants: validParticipants.length > 0 ? validParticipants : chatParticipants,
      deadline,
      priority,
    };
  }
}

/**
 * 默认任务检测器实例
 */
export const taskDetector = new TaskDetector();
